package comet.quality;

import java.util.ArrayList;
import java.util.Iterator;

import comet.util.OntologyHelper;

import com.hp.hpl.jena.ontology.ObjectProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;

public class ModuleCohesion {

	OntModel ontologyModule = null;

	ModuleCohesion(OntModel ontologyModule){
		this.ontologyModule=ontologyModule;
	}

	public double  getCohesivenessOfHierarchicalRelations() {
		double HR=0.0;
		for (Iterator<OntClass> i = ontologyModule.listClasses();  i.hasNext(); ) {
			OntClass ci = (OntClass) i.next();
			for (Iterator<OntClass> j = ontologyModule.listClasses();  j.hasNext(); ) {
				OntClass cj = (OntClass) j.next();
				HR = HR + ratioOfHierarchicalRelations(ci,cj);
			} // internal loop
		} // external for
		// make sure that size returns the number of classes within the ontology
		HR=HR/ontologyModule.size();
		return HR;	
	}

	public double  getCohesivenessOfNonHierarchicalRelations() {
		double NHR=0.0;
		for (Iterator<OntClass> i = ontologyModule.listClasses();  i.hasNext(); ) {
			OntClass ci = (OntClass) i.next();
			for (Iterator<OntClass> j = ontologyModule.listClasses();  j.hasNext(); ) {
				OntClass cj = (OntClass) j.next();
				NHR=NHR= + ratioOfNonHierarchicalRelations(ci,cj);
			} // internal loop
		} // external for
		// make sure that size returns the number of classes within the ontology
		NHR = NHR/ontologyModule.size();
		return NHR;	
	}

	// HR(ci,cj)
	private  double ratioOfHierarchicalRelations(OntClass ci, OntClass cj) {
		if(existsHierarchicalRelation(ci,cj)) 
			return 1/distance(ci,cj);
		return 0;
	}

	// NHR(ci,cj)
	private  double ratioOfNonHierarchicalRelations(OntClass ci, OntClass cj) {
		if(getNumberOfSemanticRelations(ci,cj)>0) 
			return 1/distance(ci,cj);
		return 0;
	}
	
	// returns number of relations between two concepts
	private  int distance(OntClass ci, OntClass cj) {
		int numberOfSemanticRelations = getNumberOfSemanticRelations(ci,cj);
		if(existsHierarchicalRelation(ci,cj)) return numberOfSemanticRelations+1;
		return numberOfSemanticRelations;
	}

	// checks wether two classes are linked by hierarchical relation
	// daisy check if getSuperClass does the job
	private  boolean existsHierarchicalRelation(OntClass ci, OntClass cj) {
		if(ci.getSuperClass().equals(cj)) return true;
		if(cj.getSuperClass().equals(ci)) return true;
		return false;
	}

	// returns number of transversal relations between two concepts 
	private  int getNumberOfSemanticRelations(OntClass ci, OntClass cj) {
		ArrayList<OntProperty> semanticRelations = OntologyHelper.getIncomingObjectProperties(ontologyModule,ci);
		int numberOfSemanticRelations = 0;
		for(int i=0; i<semanticRelations.size();i++) {
			ObjectProperty op = (ObjectProperty)semanticRelations.get(i);
			if(op.hasRange(cj)) numberOfSemanticRelations++;
		}
		// check the other side
		semanticRelations = OntologyHelper.getIncomingObjectProperties(ontologyModule,cj);
		for(int i=0; i<semanticRelations.size();i++) {
			ObjectProperty op = (ObjectProperty)semanticRelations.get(i);
			if(op.hasRange(ci)) numberOfSemanticRelations++;
		}
		
		return numberOfSemanticRelations;
	}
}
